/*
 * (C) Copyright 2012, by Tim Xie.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.superapk.diamond.sqllite;

import java.util.HashMap;
import com.superapk.diamond.sqllite.exception.CreateTableException;
import com.superapk.diamond.sqllite.exception.DeleteSqlException;
import com.superapk.diamond.sqllite.exception.InsertSqlException;
import com.superapk.diamond.sqllite.exception.SqlException;
import com.superapk.diamond.sqllite.exception.UpdateSqlException;
import com.superapk.diamond.util.LogUtil;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * 数据库操作类
 * 
 * @author     Tim Xie [tim.xie2008@gmail.com]
 * @date       2013-3-13
 * 
 */

public class DBManager {
	
	/**
	 * 对应数据库名字的DBManager
	 */
	private final static HashMap<String, DBManager> DB_MAP = new HashMap<String, DBManager>();
	
	private SQLiteOpenHelper mOpenHelper;
	
	private DBManager(Context context,String dbName){
		mOpenHelper = new DatabaseHelper(context,dbName);
	}
	
	/**
	 * 获取一个DB管理实例
	 * @param context
	 * @return DBManager
	 */
	public static DBManager getInstance(Context context){
		return getInstance(context,null);
	}
	
	/**
	 * 获取一个DB管理实例
	 * @param context
	 * @param dbName 数据库名
	 * @return DBManager
	 */
	public static DBManager getInstance(Context context,String dbName){
		if(dbName == null){
			dbName = DatabaseHelper.DATABASE_NAME;
		}
		DBManager instance = DB_MAP.get(dbName);
		if(instance == null){
			instance = new DBManager(context.getApplicationContext(),dbName);
		}
		return instance;
	}
	
	private static class DatabaseHelper extends SQLiteOpenHelper {
        
        private static final int DATABASE_VERSION = 1;
        
        private static final String DATABASE_NAME = "diamond.db";
        
        public DatabaseHelper(Context context,String dbName) {
            super(context, dbName, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
        	//初始化操作
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
        	//数据库升级操作
        }
    }
	
	/**
	 * 根据一个实例Bean创建表格
	 * @param tableClass
	 */
	public void createTable(Object tableClass) throws CreateTableException{
		if(tableClass == null){
			throw new CreateTableException("tableClass must be not null.");
		}
		try{
			String sqlStr = SQLBuilder.buildCreatTableSQL(tableClass);
			LogUtil.d("execSQL:" + sqlStr);
			SQLiteDatabase sqlLiteDatabase =  mOpenHelper.getWritableDatabase();
			sqlLiteDatabase.execSQL(sqlStr);
			sqlLiteDatabase.close();
		}catch(Exception e){
			throw new CreateTableException(e.getMessage());
		}
	}
	
	/**
	 * 插入一个实例Bean到数据库表
	 * @param entity
	 */
	public void saveEntity(Object entity) throws InsertSqlException{
		if(entity == null){
			throw new InsertSqlException("entity must be not null.");
		}
		try{
			String sqlStr = SQLBuilder.buildInsertSql(entity);
			LogUtil.d("execSQL:" + sqlStr);
			SQLiteDatabase sqlLiteDatabase =  mOpenHelper.getWritableDatabase();
			sqlLiteDatabase.execSQL(sqlStr);
			sqlLiteDatabase.close();
		}catch(Exception e){
			throw new InsertSqlException(e.getMessage());
		}
	}
	
	/**
	 * 更新一个实例到数据库，该实例的id必须不能为空
	 * @param entity
	 * @throws UpdateSqlException
	 */
	public void updateEntity(Object entity) throws UpdateSqlException{
		if(entity == null){
			throw new UpdateSqlException("entity must be not null.");
		}
		try{
			String sqlStr = SQLBuilder.buildUpdateSql(entity);
			LogUtil.d("execSQL:" + sqlStr);
			SQLiteDatabase sqlLiteDatabase =  mOpenHelper.getWritableDatabase();
			sqlLiteDatabase.execSQL(sqlStr);
			sqlLiteDatabase.close();
		}catch(Exception e){
			throw new UpdateSqlException(e.getMessage());
		}		
	}
	
	/**
	 * 根据Where条件更新数据
	 * @param tableClass
	 * @param whereClause
	 * @param whereArgs
	 * @throws UpdateSqlException
	 */
	public void updateByWhere(Object entity,String whereClause,String[] whereArgs) throws UpdateSqlException{
		if(entity == null){
			throw new UpdateSqlException("entity must be not null.");
		}
		try{
			if(!whereClause.contains("?")){
				throw new UpdateSqlException("param whereClause must be contains ? character");
			}
			if(whereArgs == null || whereArgs.length == 0){
				throw new UpdateSqlException("param whereArgs is illegal.");
			}
			TableInfo tableInfo = TableInfo.getTableInfo(entity.getClass());
			String tableName = tableInfo.getTableName();
			HashMap<String, Object> columnKeyValues = SQLBuilder.getColumnKeyValues(entity);
			if(columnKeyValues != null && columnKeyValues.size() > 0){
				ContentValues contentValues = ContentValuesUtil.conversionContentValues(columnKeyValues);
				SQLiteDatabase sqlLiteDatabase =  mOpenHelper.getWritableDatabase();
				sqlLiteDatabase.update(tableName, contentValues, whereClause, whereArgs);
				sqlLiteDatabase.close();
			}
		}catch(Exception e){
			throw new UpdateSqlException(e.getMessage());
		}
	}
	
	/**
	 * 根据一个实例Bean删除表格
	 * @param tableClass
	 */
	public void deleteTable(Object tableClass) throws DeleteSqlException{
		if(tableClass == null){
			throw new DeleteSqlException("tableClass must be not null.");
		}
		try{
			TableInfo tableInfo = TableInfo.getTableInfo(tableClass.getClass());
			SQLiteDatabase sqlLiteDatabase =  mOpenHelper.getWritableDatabase();
			//where whereArg为null，全部删除
			sqlLiteDatabase.delete(tableInfo.getTableName(), null, null);
			sqlLiteDatabase.close();
		}catch(Exception e){
			throw new DeleteSqlException(e.getMessage());
		}
	}
	
	/**
	 * 根据一个实例删除数据库的记录，该实例的主键值必须不能为空
	 * @param entity
	 * @throws DeleteSqlException
	 */
	public void deleteEntity(Object entity) throws DeleteSqlException{
		if(entity == null){
			throw new DeleteSqlException("entity must be not null.");
		}
		try{
			String sqlStr = SQLBuilder.buildDeleteSql(entity);
			LogUtil.d("execSQL:" + sqlStr);
			SQLiteDatabase sqlLiteDatabase =  mOpenHelper.getWritableDatabase();
			sqlLiteDatabase.execSQL(sqlStr);
			sqlLiteDatabase.close();
		}catch(Exception e){
			throw new DeleteSqlException(e.getMessage());
		}		
	}
	
	/**
	 * 根据where条件删除记录
	 * @param tableClass
	 * @param whereClause
	 * @param whereArgs
	 * @return 删除了多少条
	 * @throws DeleteSqlException
	 * 
	 */
	public int deleteByWhere(Object tableClass,String whereClause,String[] whereArgs) throws DeleteSqlException{
		int count = 0;
		if(tableClass == null){
			throw new DeleteSqlException("tableClass must be not null.");
		}
		try{
			TableInfo tableInfo = TableInfo.getTableInfo(tableClass.getClass());
			String tableName = tableInfo.getTableName();
			SQLiteDatabase sqlLiteDatabase =  mOpenHelper.getWritableDatabase();
			count = sqlLiteDatabase.delete(tableName, whereClause, whereArgs);
			sqlLiteDatabase.close();
		}catch(Exception e){
			throw new DeleteSqlException(e.getMessage());
		}
		return count;
	}
	
	public <T> T queryById(Class<T> entityClass,int id) throws SqlException{
		if(entityClass == null){
			throw new SqlException("entityClass must be not null.");
		}
		try{
			T entity = entityClass.newInstance();
			//表名
			TableInfo tableInfo = TableInfo.getTableInfo(entity.getClass());
			//所有字段
			HashMap<String, FieldInfo> fieldInfos = tableInfo.getFieldInfoMap();
			ExecSQL execSQL = SQLBuilder.buildQuerySqlById(entity,id);
			LogUtil.d("execSQL:" + execSQL.getExecSql());
			SQLiteDatabase sqlLiteDatabase =  mOpenHelper.getWritableDatabase();
			//从数据库查询数据
			Cursor cursor = sqlLiteDatabase.rawQuery(execSQL.getExecSql(), execSQL.getBindStringArgs());
			// 遍历游标
			if (cursor != null && cursor.getCount() != 0 && cursor.moveToFirst()) {
				//数据库的所有字段，columnCount应该等于fieldInfos.size()
				int columnCount = cursor.getColumnCount();
				for(int i = 0;i < columnCount;i++){
					String columnName = cursor.getColumnName(i);
					//对应的字段
					FieldInfo columnValue = fieldInfos.get(columnName);
					//把数据库的值赋值给对象FieldInfo
					//columnValue.setValue(receiver, entity);
				}
			}			
			sqlLiteDatabase.close();
			//返回实例
			return entity;
		}catch(Exception e){
			throw new DeleteSqlException(e.getMessage());
		}
	}

}
